//-----------------------------------------------------------------------
// <copyright file="NativeMethods.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Wrappers for Native Methods</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks
{
    using System.Runtime.InteropServices;
    using System;
    using System.Security.Permissions;
    using System.Security;
    
    using BOOL = System.Boolean;
    using DWORD = System.UInt32;
    using LPWSTR = System.String;
    using NET_API_STATUS = System.UInt32;

    /// <summary>
    /// Summary description for NativeMethods.
    /// </summary>

    [SuppressUnmanagedCodeSecurity]
    internal sealed class NativeMethods
    {
        /// <summary>
        /// Prevents a new instance of the NativeMethods class being instantiated.
        /// </summary>
        private NativeMethods()
        {
        }

        internal const string Advapi32 = "advapi32.dll";

        internal const int LOGON32_LOGON_INTERACTIVE = 2;
        internal const int LOGON32_PROVIDER_DEFAULT = 0;

        internal const int HWND_BROADCAST = 0xffff;

        internal const int WM_SETTINGCHANGE = 0x001A;

        internal const int SMTO_NORMAL = 0x0000;

        internal const int SMTO_BLOCK = 0x0001;

        internal const int SMTO_ABORTIFHUNG = 0x0002;

        internal const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;

        internal const int MAX_PATH = 260;

        internal const uint RPC_C_AUTHN_DEFAULT = 0xFFFFFFFF;
        
        internal const uint RPC_C_AUTHZ_DEFAULT = 0xFFFFFFFF;
        
        internal const uint RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6;

        internal const uint EOAC_DEFAULT = 0x800;

        internal const NET_API_STATUS NERR_Success = 0;

        internal const DWORD USE_WILDCARD = unchecked((DWORD)(-1));
        internal const DWORD USE_DISKDEV = 0;
        internal const DWORD USE_SPOOLDEV = 1;
        internal const DWORD USE_IPC = 3;

        internal const DWORD USE_NOFORCE = 0;
        internal const DWORD USE_FORCE = 1;
        internal const DWORD USE_LOTS_OF_FORCE = 2;

        internal const DWORD ERROR_INVALID_PARAMETER = 87;

        internal const DWORD USE_LOCAL_PARMNUM = 1;
        internal const DWORD USE_REMOTE_PARMNUM = 2;
        internal const DWORD USE_PASSWORD_PARMNUM = 3;
        internal const DWORD USE_ASGTYPE_PARMNUM = 4;
        internal const DWORD USE_USERNAME_PARMNUM = 5;
        internal const DWORD USE_DOMAINNAME_PARMNUM = 6;

        internal const DWORD ERROR_NOT_CONNECTED = 2250;

        [DllImportAttribute("USER32")]
        /*internal static extern int SendMessageTimeout(System.IntPtr hWnd,
                                      int Msg,
                                      System.IntPtr wParam,
                                      System.IntPtr lParam,
                                      int fuFlags,
                                      int uTimeout,
                                      System.IntPtr lpdwResult);
       
            internal static extern int SendMessageTimeout(System.IntPtr hWnd,
                int Msg,
                System.IntPtr wParam,
                string lParam,
                int fuFlags,
                int uTimeout,
                System.IntPtr lpdwResult);
     */
        internal static extern int SendMessageTimeout(int hWnd,
            int Msg,
            int wParam,
            string lParam,
            int fuFlags,
            int uTimeout,
            int lpdwResult);

        // Import the Kernel32 dll file.
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetEnvironmentVariable(string lpName, string lpValue);

        /// <summary>
        /// This demands permissions to set an environment variable and then sets
        /// it on the current process
        /// </summary>
        /// <param name="environmentVariable">Name of variable</param>
        /// <param name="variableValue">Value of variable</param>
        /// <returns></returns>
        internal static bool SetEnvironmentVariableEx(string environmentVariable, string variableValue)
        {
            // Get the write permission to set the environment variable.
            EnvironmentPermission environmentPermission = new EnvironmentPermission(EnvironmentPermissionAccess.Write, environmentVariable);
            environmentPermission.Demand();
            return SetEnvironmentVariable(environmentVariable, variableValue);
        }

        [DllImport("ole32.dll", CharSet = CharSet.Auto)]
        internal static extern uint CoSetProxyBlanket(
                                              IntPtr pProxy,
                                              uint dwAuthnSvc,
                                              uint dwAuthzSvc,
                                              IntPtr pServerPrincName,
                                              uint dwAuthnLevel,
                                              uint dwImpLevel,
                                              IntPtr pAuthInfo,
                                              uint dwCapababilities);

        /// <summary>
        /// Define RPC_C_IMP_LEVEL constants
        /// </summary>
        internal enum RpcImpLevel
        {
            Default = 0,
            Anonymous,
            Identify,
            Impersonate,
            Delegate
        }

        internal enum VMState
        {
            VMState_Invalid = 0,
            VMState_TurnedOff = 1,
            VMState_Saved = 2,
            VMState_TurningOn = 3,
            VMState_Restoring = 4,
            VMState_Running = 5,
            VMState_Paused = 6,
            VMState_Saving = 7,
            VMState_TurningOff = 8,
            VMState_MergingDrives = 9,
            VMState_DeleteMachine = 10,
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        internal struct USE_INFO_2
        {
            internal LPWSTR ui2_local;
            internal LPWSTR ui2_remote;
            internal LPWSTR ui2_password;
            internal DWORD ui2_status;
            internal DWORD ui2_asg_type;
            internal DWORD ui2_refcount;
            internal DWORD ui2_usecount;
            internal LPWSTR ui2_username;
            internal LPWSTR ui2_domainname;
        }

        
        [DllImport("NetApi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        internal static extern NET_API_STATUS NetUseAdd(
            LPWSTR UncServerName,
            DWORD Level,
            ref USE_INFO_2 Buf,
            out DWORD ParmError);

        [DllImport("NetApi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        internal static extern NET_API_STATUS NetUseDel(
           LPWSTR UncServerName,
           LPWSTR UseName,
           DWORD ForceCond);

        /// <summary>
        /// The IAssemblyCache interface.
        /// </summary>
        /// <remarks>
        /// Defined in Microsoft KB article 317540.
        /// http://support.microsoft.com/default.aspx?scid=kb;en-us;317540
        /// </remarks>
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("e707dcde-d1cd-11d2-bab9-00c04f8eceae")]
        internal interface IAssemblyCache
        {
            [PreserveSig()]
            int UninstallAssembly(
                int dwFlags,
                [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName,
                IntPtr pvReserved,
                out int pulDisposition);

            [PreserveSig()]
            int QueryAssemblyInfo(
                int dwFlags,
                [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName,
                IntPtr pAsmInfo);

            [PreserveSig()]
            int CreateAssemblyCacheItem(
                int dwFlags,
                IntPtr pvReserved,
                out /*IAssemblyCacheItem*/IntPtr ppAsmItem,
                [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName);

            [PreserveSig()]
            int CreateAssemblyScavenger(out object ppAsmScavenger);

            [PreserveSig()]
            int InstallAssembly(int dwFlags,
                [MarshalAs(UnmanagedType.LPWStr)] string pszManifestFilePath,
                IntPtr pvReserved);
        }

        /// <summary>
        /// Fusion function to get an IAssemblyCache interface.
        /// </summary>
        /// <param name="ppAsmCache">
        /// An output parameter that will return the IAssemblyCache interface.
        /// </param>
        /// <param name="dwReserved">
        /// Reserved and must be zero.
        /// </param>
        /// <returns>
        /// A return code where zero is success and anything else is a COM
        /// failure code.
        /// </returns>
        [DllImport("fusion.dll")]
        internal static extern int CreateAssemblyCache(
            out IAssemblyCache ppAsmCache,
            int dwReserved);


        [DllImport(NativeMethods.Advapi32, CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern bool LogonUser(
            [MarshalAs(UnmanagedType.LPTStr)] string lpszUsername,
            [MarshalAs(UnmanagedType.LPTStr)] string lpszDomain,
            [MarshalAs(UnmanagedType.LPTStr)] string lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            out IntPtr phToken
            );

        //TODO does this return an int or a bool
        //TODO Should the hToken going in be a HandleRef
        [DllImport(NativeMethods.Advapi32, CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
    	

    }
}
